#ifndef JS_COLORCUBE_H
#define JS_COLORCUBE_H

#include <DDImage/Iop.h>
#include <DDImage/Black.h>
#include <DDImage/AxisOp.h>
#include <DDImage/Row.h>
#include <DDImage/Pixel.h>
#include <DDImage/Knobs.h>
#include <DDImage/Knob.h>
#include <DDImage/ViewerContext.h>
#include <DDImage/Thread.h>
#include <DDImage/Matrix4.h>
#include <DDImage/DDMath.h>
#include <DDImage/LookupCurves.h>
#include <DDImage/Tile.h>
#include <DDImage/Thread.h>

namespace DD
{
    namespace Image
    {
        static const CurveDescription warperDefaults[] = { { "R", "y C 0 0" }, { "G", "y C 0 0" }, { "B", "y C 0 0" }, { "Sat", "y C 0 0" }, { 0 } };
        class js_ColorCube: public Iop
        {
            Hash m_hash;
            Hash m_sampleHash;
            int m_displayListId;
            float m_drawSize;
            float m_centerColor[3];
            bool m_displaySample;
            float m_sampleColor[3];
            bool m_doKey;
            bool m_doKeyDraw;

            bool m_doDespill;
            bool m_blueScreen;
            float m_colorBalance;
            float m_colorMult;
            bool m_doWarp;
            LookupCurves m_warperCurve;

            bool m_doKKey;
            float m_kTolMin;
            float m_kTolMax;

            Matrix4 m_tolMat;
            Matrix4 m_tolMatInv;
            Matrix4 m_softMat;
            Matrix4 m_softMatInv;

            std::vector<Vector3> m_keySample;

            public:
                const char* input_label(int n, char*) const;
                void _request(int x, int y, int r, int t, ChannelMask channels, int count);
                void _validate(bool);
                void engine(int y, int x, int r, ChannelMask channels, Row& out);

                void updateColorList( void );

                js_ColorCube(Node *node);

                int minimum_inputs() const
                {
                    return 3;
                }

                int maximum_inputs() const
                {
                    return 3;
                }

                bool test_input(int input, Op* op) const;
                Op* default_input(int n) const;

                void knobs(Knob_Callback f);

                const char *Class() const
                {
                    return "js_ColorCube";
                }
                const char *node_help() const
                {
                    return "";
                }

                void build_handles(ViewerContext* ctx);

                void draw_handle(ViewerContext* ctx);

                static const Description description;

                // Helper fuctions
                void drawCircle(const float radius, const float r, const float g, const float b);
                void drawBox(const float size, const float r, const float g, const float b, const bool color = false );
                float deg_to_rad(float deg);
                float luma( const float r, const float g, const float b );
                void updateMatrices( void );
                float js_3dKey( const Vector3 & pos );
                float js_KKey( const Vector3 & pos );
                void js_Warp( float & r, float & g, float & b );
            };
    }

}

#endif  /* JS_COLORCUBE_H */


